package org.jeecg.modules.zcgl.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ccqtgb.sxp.partner.security.MessageProcess;
import com.ccqtgb.sxp.partner.security.bo.RequestData;
import com.ccqtgb.sxp.partner.security.bo.ResponseData;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.properties.config.CCQTGBPropertyConfig;
import org.jeecg.common.system.base.entity.DelFlagBaseEntity;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.HttpClientUtil;
import org.jeecg.common.util.ReflectHelper;
import org.jeecg.modules.api.enums.TradeStatusEnum;
import org.jeecg.modules.api.utils.ApiDataUtils;
import org.jeecg.modules.api.vo.param.PaymentConfirmationParamVo;
import org.jeecg.modules.api.vo.param.PaymentParamVo;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.zcgl.entity.*;
import org.jeecg.modules.zcgl.enums.CcqtgbLogTypeEnum;
import org.jeecg.modules.zcgl.enums.PayRentTypeEnum;
import org.jeecg.modules.zcgl.enums.YesNoEnum;
import org.jeecg.modules.zcgl.mapper.ReceivablesInfoMapper;
import org.jeecg.modules.zcgl.mapper.StatementAccountDetailsMapper;
import org.jeecg.modules.zcgl.mapper.StatementAccountDetailsOrderMapper;
import org.jeecg.modules.zcgl.mapper.StatementAccountMapper;
import org.jeecg.modules.zcgl.service.ICcqtgbLogService;
import org.jeecg.modules.zcgl.service.IOrderPrestoreService;
import org.jeecg.modules.zcgl.service.IReceivablesInfoService;
import org.jeecg.modules.zcgl.service.IStatementAccountService;
import org.jeecg.modules.zcgl.vo.StatementAccountItemsResultVO;
import org.jeecg.modules.zcgl.vo.StatementAccountPostVO;
import org.jeecg.modules.zcgl.vo.StatementAccountResultVO;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description: 对账单信息
 * @Author: jeecg-boot
 * @Date: 2021-01-15
 * @Version: V1.0
 */
@Log
@Service
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class StatementAccountServiceImpl extends ServiceImpl<StatementAccountMapper, StatementAccount> implements IStatementAccountService {

    @Resource
    private StatementAccountMapper statementAccountMapper;
    @Resource
    private StatementAccountDetailsMapper statementAccountDetailsMapper;
    @Resource
    private StatementAccountDetailsOrderMapper statementAccountDetailsOrderMapper;
    @Resource
    private ReceivablesInfoMapper receivablesInfoMapper;
    @Autowired
    private CCQTGBPropertyConfig ccqtgbPropertyConfig;
    @Autowired
    private IOrderPrestoreService orderPrestoreService;
    @Autowired
    private IReceivablesInfoService receivablesInfoService;
    @Autowired
    private ICcqtgbLogService ccqtgbLogService;

    @Override
    @Transactional
    public boolean saveOrUpdateMain(StatementAccount statementAccount, List<StatementAccountDetails> statementAccountDetailsList) {

        StatementAccount account = statementAccountMapper.selectByDateAndCompanyId(statementAccount.getDate(), statementAccount.getCompanyId());
        if (account == null){
            account = new StatementAccount();
        }
        BeanUtils.copyProperties(statementAccount, account, ReflectHelper.getFiledName(DelFlagBaseEntity.class));
       account.setCompanyId(statementAccount.getCompanyId());
       super.saveOrUpdate(account);

        statementAccountDetailsMapper.deleteByMainId(account.getId());
        statementAccountDetailsOrderMapper.deleteByStatementAccountId(account.getId());

        if (statementAccountDetailsList != null && statementAccountDetailsList.size() > 0) {
            for (StatementAccountDetails entity : statementAccountDetailsList) {
                //外键设置
                entity.setStatementAccountId(account.getId());
                entity.setCompanyId(account.getCompanyId());
                boolean bool = false;
                try {
                    if (entity.getOrderType() != null && entity.getOrderType().intValue() == PayRentTypeEnum.RENTCZ.getStatus().intValue()){
                        PaymentParamVo vo = new PaymentParamVo();
                        vo.setCustomerId(entity.getCustomerId());
                        vo.setTradeStatus(TradeStatusEnum.SUCCESS.getKey());
                        vo.setTradeMessage(entity.getTradeMessage());
                        vo.setTradeTime(DateUtils.date2Str(entity.getTradeFinishTime(), DateUtils.yyyymmdd_hhmmss.get()));
                        vo.setTransactionId(entity.getTransactionId());
                        vo.setTradeType(entity.getTradeType());
                        vo.setAmountMoney(entity.getTotalFee().multiply(new BigDecimal(100)).longValue());
                        vo.setRecordedCompanyName(account.getRecordedCompanyName());
                        vo.setPayeeName(account.getPayeeName());
                        vo.setPayeeAccount(account.getPayeeAccount());
                        vo.setPayeeBankDeposit(account.getPayeeBankDeposit());

                        //20210608 尹涛 --插入合同编码
                        vo.setContractNum(entity.getContractNum());
                        //20210608 尹涛 --插入合同编码

                        //预存处理
                        bool = orderPrestoreService.saveAndCustomerBalance(vo);
                    } else if (entity.getOrderType() != null && entity.getOrderType().intValue() == PayRentTypeEnum.RENTJF.getStatus().intValue()){
                        PaymentConfirmationParamVo vo = new PaymentConfirmationParamVo();

                        if (StringUtils.isBlank(entity.getOrderIds())){
                            throw new JeecgBootException("待付款信息ID不能为空！");
                        }
                        vo.setOrderIds(Arrays.asList(entity.getOrderIds().split(CommonConstant.DEFAULT_SEPARATOR)));
                        vo.setRecordedCompanyId(entity.getCompanyId());
                        vo.setCustomerId(entity.getCustomerId());
                        vo.setTradeStatus(TradeStatusEnum.SUCCESS.getKey());
                        vo.setTradeMessage(entity.getTradeMessage());
                        vo.setTradeTime(DateUtils.date2Str(entity.getTradeFinishTime(), DateUtils.yyyymmdd_hhmmss.get()));
                        vo.setTransactionId(entity.getTransactionId());
                        vo.setTradeType(entity.getTradeType());
                        vo.setAmountMoney(entity.getTotalFee().multiply(new BigDecimal(100)).longValue());
                        vo.setRecordedCompanyName(account.getRecordedCompanyName());
                        vo.setPayeeName(account.getPayeeName());
                        vo.setPayeeAccount(account.getPayeeAccount());
                        vo.setPayeeBankDeposit(account.getPayeeBankDeposit());
                        //付款处理
                        bool = receivablesInfoService.paymentConfirmation(vo);
                    } else {
                        entity.setCompareMessage("非预存或缴费！");
                    }
                } catch (JeecgBootException e) {
                    entity.setCompareMessage(e.getMessage());
                } catch (Exception e){
                    e.printStackTrace();
                    entity.setCompareMessage("和本地对比失败！");
                }
                entity.setIzCompareSuccess(bool ? YesNoEnum.YES.getStatus() : YesNoEnum.NO.getStatus());
                statementAccountDetailsMapper.insert(entity);
                this.creatorAndInsertOrder(entity);
            }
        }
        return true;
    }


    private void creatorAndInsertOrder(StatementAccountDetails entity){
        if (StringUtils.isNotBlank(entity.getOrderIds())){
            String[] orderIdAttr = entity.getOrderIds().split(CommonConstant.DEFAULT_SEPARATOR);
            for (String orderId : orderIdAttr) {
                ReceivablesInfo receivablesInfo = receivablesInfoMapper.selectById(orderId);
                if (receivablesInfo == null){
                    continue;
                }
                StatementAccountDetailsOrder order = new StatementAccountDetailsOrder();
                BeanUtils.copyProperties(entity, order, ReflectHelper.getFiledName(DelFlagBaseEntity.class));
                order.setCompanyId(receivablesInfo.getCompanyId());
                order.setStatementAccountDetailsId(entity.getId());
                statementAccountDetailsOrderMapper.insert(order);
            }
        }
    }

    @Override
    @Transactional
    public void delMain(String id) {
        //删除
        LambdaQueryWrapper<StatementAccountDetails> detailsQueryWrapper = new LambdaQueryWrapper<>();
        detailsQueryWrapper.eq(StatementAccountDetails::getStatementAccountId, id);
        statementAccountDetailsMapper.delete(detailsQueryWrapper);
        LambdaQueryWrapper<StatementAccountDetailsOrder> orderQueryWrapper = new LambdaQueryWrapper<>();
        orderQueryWrapper.eq(StatementAccountDetailsOrder::getStatementAccountId, id);
        statementAccountDetailsOrderMapper.delete(orderQueryWrapper);
        statementAccountMapper.deleteById(id);

        /*//物理删除
        statementAccountDetailsMapper.deleteByMainId(id);
        statementAccountDetailsOrderMapper.deleteByStatementAccountId(id);
        statementAccountMapper.deletePhysicallyById(id);*/
    }

    @Override
    @Transactional
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            this.delMain(id.toString());
        }
    }

    @Override
//    @Transactional
    public void statementAccountByDepart(SysDepart depart, Date date) {
        try {
            if (depart == null){
                throw new JeecgBootException("公司没有，更新失败！");
            }
            if (StringUtils.isBlank(depart.getPartnerNo())){
                throw new JeecgBootException("公司没有商户号，更新失败！");
            }
            CcqtgbLog ccqtgbLog = ccqtgbLogService.selectByCompanyIdAndSucceedAndDateAndType(depart.getId(), null, date, CcqtgbLogTypeEnum.STATEMENT_ACCOUNT.getStatus());
            if (ccqtgbLog == null) {
                ccqtgbLog = new CcqtgbLog();
                ccqtgbLog.setPageNo(0);
            } else if (YesNoEnum.YES.getStatus() == ccqtgbLog.getIzSucceed().intValue()) {
                return;
            }
            //组装请求数据
            StatementAccountPostVO vo = new StatementAccountPostVO();
            vo.setOrdertype("0001");
            vo.setPartner(depart.getPartnerNo());
            vo.setTranstime(DateUtils.yyyyMMdd.get().format(date));
            ResponseData<String> messageCallBack = MessageProcess.getResponseMessageCallBack(vo,
                    vo.getPartner(), ccqtgbPropertyConfig.getPrivateKeyPath(), ccqtgbPropertyConfig.getAesKey(),
                    null, 200, "");
            //发送post请求
            String resultString = HttpClientUtil.doPostJson(ccqtgbPropertyConfig.getStatementAccountUrl(), JSON.toJSONString(messageCallBack));
            log.info(depart.getDepartName() + "对账单下载返回结果：" + resultString);
            //返回结果解密
//            RequestData<Map> dataReslt = ApiDataUtils.getRequestData(resultString, Map.class);
            RequestData<StatementAccountResultVO> dataReslt = ApiDataUtils.getRequestData(resultString, StatementAccountResultVO.class);
            log.info("对账单下载返回解析结果=======================：" + dataReslt);
            StatementAccountResultVO resultVO = dataReslt.getBody();
            if ("0000".equalsIgnoreCase(resultVO.getRetcode())) {
                StatementAccount statementAccount = new StatementAccount();
                BeanUtils.copyProperties(resultVO, statementAccount, "date");
                statementAccount.setRetCode(resultVO.getRetcode());
                statementAccount.setRetShow(resultVO.getRetmsg());
                statementAccount.setDate(date);
                statementAccount.setCompanyId(depart.getId());
                statementAccount.setSysOrgCode(depart.getOrgCode());
                //TODO
                statementAccount.setRecordedCompanyName(depart.getDepartName());

                List<StatementAccountDetails> statementAccountDetailsList = this.creatorDetails(resultVO.getItems());
                boolean bool = ((StatementAccountServiceImpl) AopContext.currentProxy()).saveOrUpdateMain(statementAccount, statementAccountDetailsList);
                ccqtgbLog.setType(CcqtgbLogTypeEnum.STATEMENT_ACCOUNT.getStatus());
                ccqtgbLog.setPageCount(0);
                ccqtgbLog.setPageNo(0);
                ccqtgbLog.setIzSucceed(bool ? YesNoEnum.YES.getStatus() : YesNoEnum.NO.getStatus());
                ccqtgbLog.setDate(date);
                ccqtgbLog.setCompanyId(depart.getId());
                ccqtgbLog.setSysOrgCode(depart.getOrgCode());
                ccqtgbLogService.saveOrUpdate(ccqtgbLog);
//                this.saveOrUpdateMain(statementAccount, statementAccountDetailsList);
            } else {
                throw new JeecgBootException("对账单下载失败：" + resultVO.getRetmsg());
            }
        } catch (JeecgBootException e) {
            throw new JeecgBootException(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            throw new JeecgBootException("对账单下载失败！");
        }
    }

    private List<StatementAccountDetails> creatorDetails(List<StatementAccountItemsResultVO> items){
        List<StatementAccountDetails> statementAccountDetailsList = new ArrayList<>();
        if (items != null && items.size() > 0) {
            items.stream().forEach(item -> {
                StatementAccountDetails details = new StatementAccountDetails();
                details.setCustomerId(item.getOthmemberno());
                details.setPartnerNo(item.getPartnerNo());
                details.setOutTradeNo(item.getOut_trade_no());
                details.setTradeMessage(item.getTradeMessage());
                details.setTradeFinishTime(DateUtils.str2Date(item.getTradefinishtime(), DateUtils.yyyymmdd_hhmmss.get()));
                if ("0".equalsIgnoreCase(item.getTrade_state())){
                    details.setTradeState(TradeStatusEnum.SUCCESS.getStatus());
                }
                details.setTotalFee(item.getTotal_fee());
                details.setOrderIds(item.getOrderIds());
                details.setOrderType(PayRentTypeEnum.getStatusByKey(item.getPayrenttype()));
                details.setTradeType(item.getTradeType());
                details.setTransactionId(item.getTransactionId());
                //20210608 尹涛 --插入合同编码
                details.setContractNum(item.getContractNum());
                //20210608 尹涛 --插入合同编码
                statementAccountDetailsList.add(details);
            });
        }
        return statementAccountDetailsList;
    }

}
